package com.qdlc.p2p.biz.executer.impl;

import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.qdlc.p2p.biz.service.AccountService;
import com.qdlc.p2p.common.constant.ChangeReasonType;
import com.qdlc.p2p.common.constant.Global;
import com.qdlc.p2p.common.constant.LogTplNid;
import com.qdlc.p2p.common.exception.AccountException;
import com.qdlc.p2p.common.util.BeanUtil;
import com.qdlc.p2p.common.util.LogFactory;
import com.qdlc.p2p.dal.common.SystemConfigHelper;
import com.qdlc.p2p.dal.dao.AccountDao;
import com.qdlc.p2p.dal.dto.Account;
import com.qdlc.p2p.dal.util.SystemConfigs;

/**
 * 资金变更及资金变更原因记录类
 *
 * @version 1.0
 */
@Service
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class AccountChangeExecuter {

    private static Logger tradeLogger = LogFactory.TRADE_LOGGER;

    /**
     * 账户ID
     */
    private long userId;

    /**
     * 操作金额
     */
    private double operateMoney;

    private AccountDao accountDao;

	private AccountService accountService;

    /**
     * 变更原因
     */
    private ChangeReasonType changeReasonType;

    private AccountChangeExecuter(Builder builder) {
        accountDao = (AccountDao) BeanUtil.getBean("accountDao");
		accountService = (AccountService) BeanUtil.getBean("accountService");
        this.userId = builder.userId;
        this.operateMoney = builder.operateMoney;
        this.changeReasonType = builder.changeReasonType;
    }

    public static class Builder {

        private long userId;

        private double operateMoney;

        private ChangeReasonType changeReasonType;

        public AccountChangeExecuter build() {
            if (userId <= 0) {
                throw new AccountException("用户ID不能为空!");
            }

            if (operateMoney == 0) {
                throw new AccountException("变更金额不能为0!");
            }

            if (changeReasonType == null) {
                throw new AccountException("变更原因不能为空");
            }
            return new AccountChangeExecuter(this);
        }

        public AccountChangeExecuter build(long userId, double operateMoney, ChangeReasonType changeReasonType) {
            if (userId <= 0) {
                throw new AccountException("用户ID不能为空!");
            }

            if (operateMoney == 0) {
                throw new AccountException("变更金额不能为0!");
            }

            if (changeReasonType == null) {
                throw new AccountException("变更原因不能为空");
            }
            this.userId = userId;
            this.operateMoney = operateMoney;
            this.changeReasonType = changeReasonType;
            return new AccountChangeExecuter(this);
        }

        public Builder setUserId(long userId) {
            this.userId = userId;
            return this;
        }

        public Builder setOperateMoney(double operateMoney) {
            this.operateMoney = operateMoney;
            return this;
        }

        public Builder setChangeReasonType(ChangeReasonType changeReasonType) {
            this.changeReasonType = changeReasonType;
            return this;
        }
    }

    public boolean change() {
        return change(null);
    }

    /**
     * PS 资金变更
     * 需在同一事务内执行
     *
     * @return
     */
    public boolean change(Map<String, Object> formatMap) {
        Account account = accountDao.findByUserId( this.userId);
        double operMoney = this.operateMoney;
        if (account == null) {
            tradeLogger.error(String.format("用户[%d]对应的帐户不存在!", this.userId));
            return false;
        }

        // 日志
        switch (changeReasonType) {
            case RED_ENVELOPE:
                tradeLogger.info(String.format("用户[%d]进行虚拟红包兑现", this.userId));
                break;
            case CASH_ENVELOPE:
                tradeLogger.info(String.format("用户[%d]进行现金红包兑现", this.userId));
                break;
            case EXPERIENCE_INTEREST:
                tradeLogger.info(String.format("用户[%d]进行体验金利息兑现", this.userId));
                break;
        }

        // 兑现业务处理
        switch (changeReasonType) {
            case RED_ENVELOPE:
            case CASH_ENVELOPE:
            case EXPERIENCE_INTEREST:
				Global.setTransfer(LogTplNid.LOG_TPL_KEY, changeReasonType.getCategoryName());
				Global.setTransfer("web_url", SystemConfigHelper.getValue(SystemConfigHelper.Nid.WEB_URL));
				Global.setTransfer("userId", this.userId);
				Global.setTransfer("operateMoney", operMoney);
				accountService.revokeCapitalAndTotal(this.userId, SystemConfigs.ADMIN_ID, operMoney);
                return true;
        }
        return false;
    }
}
